/*
 * @Author: dingyuwen ding_yuwen@163.com
 * @Date: 2023-01-09 16:00:06
 * @LastEditTime: 2023-09-19 15:43:38
 * @LastEditors: DingYuwen 43669762+DingYuwen@users.noreply.github.com
 * @Description:
 */

import { $authToken } from '@tourfly/api';
import qs from 'qs';
import { FC, ReactElement, useState } from 'react';
import { useEffect } from 'react';
import { Navigate, useLocation } from 'react-router-dom';

import { RouteMeta } from './index';

import userService from '@/api/user.service';

import { CustomLoader } from '@/common/components/NewLoading';
import { getToken, isNullOrWhitespace, removeToken } from '@/common/utils';
import { useAppDispatch, useAppSelector } from '@/store/hooks';
import { setIsLogin, setUserInfo } from '@/store/user';

const WHITE_LIST = ['/signin', '/404'];

//全局路由守卫
interface PropsType {
  meta: RouteMeta;
  element: ReactElement;
}
const Guard: FC<PropsType> = (props) => {
  let { element } = props;
  const { auth } = props.meta;
  const dispatch = useAppDispatch();
  const { pathname: to, search } = useLocation();
  const { isLogin, userInfo } = useAppSelector((state) => state.user);
  const [nextPath, setNextPath] = useState<string>(to);

  const [loading, setLoading] = useState<boolean>(true);

  useEffect(() => {
    if (!auth || WHITE_LIST.includes(to) || isLogin) {
      // 已登录、白名单、无需校验的默认所有权限，直接放行

      setNextPath(to);
      setLoading(false);
    }
    const queryObj = qs.stringify({
      ...qs.parse(search.slice(1)),
      redirect: to,
    });

    if (isNullOrWhitespace(getToken())) {
      /** 没有token的情况 */
      setNextPath(`/signin?${queryObj}`);
      setLoading(false);
    } else {
      /** 有token的情况 */
      if (to === '/signin') {
        setNextPath('/');
        setLoading(false);
      }
      if (!isLogin && getToken() && to.indexOf('/signin') === -1) {
        // 校验token
        userService
          .getUserInfo()
          .then((res) => {
            if (!res.rt || !res.rt.token || !res.rt.userInfo) {
              removeToken();
              $authToken.set(undefined);
              setNextPath(`/signin?${queryObj}`);
            } else {
              dispatch(setUserInfo(res.rt.userInfo));
              dispatch(setIsLogin(true));
            }
          })
          .catch(() => {
            removeToken();
            $authToken.set(undefined);
            setNextPath(`/signin?${queryObj}`);
          })
          .finally(() => {
            setLoading(false);
          });
      }
    }
  }, [auth, to, search, isLogin, dispatch]);

  if (loading) {
    return <CustomLoader />;
  } else {
    // if (title) {
    //   // 动态修改页面title
    //   document.title = title || '图蝇';
    // }
    if (isLogin && userInfo.username) {
      return element;
    }
    if (nextPath && nextPath !== to) {
      element = <Navigate to={nextPath} replace={true} />;
    }
    return element;
  }
};

export default Guard;
